﻿using XmlStudio.Utilities;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using XmlStudio.DataLayer;
using XmlStudio.Interfaces;

namespace XmlStudio.Tests
{
    
    
    /// <summary>
    ///This is a test class for TreeBuilderTest and is intended
    ///to contain all TreeBuilderTest Unit Tests
    ///</summary>
    [TestClass()]
    public class TreeBuilderTest
    {
        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test simpleTypes
        // 
        //You can use the following additional simpleTypes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///A test for BuildTree
        ///</summary>
        [TestMethod()]
        public void BuildTreeTest()
        {
            string xml =
@"<root>
	<child1>
		<subChild1 />
		<subChild2 />
		<subChild3 />
	</child1>
	<child2>
		<subChild1>
		</subChild1>
		<subChild2>
			<subSubChild1>
				<subSubSubChild1 />
				<subSubSubChild2 />
				<subSubSubChild3 />
			</subSubChild1>
			<subSubChild2>
				<subSubSubChild1 />
			</subSubChild2>
			<subSubChild3>
				<subSubSubChild1 />
				<subSubSubChild2 />
			</subSubChild3>
		</subChild2>
		<subChild3 />
		<subChild4 />
	</child2>
	<child3>
		<subChild1 />
	</child3>
</root>";
            
            var root = TreeBuilder.BuildTree(xml);

            Assert.IsNotNull(root);
            Assert.IsTrue(root.ChildNodes.Count == 3);
            Assert.IsTrue(root.ChildNodes[0].ChildNodes.Count == 3);
            Assert.IsTrue(root.ChildNodes[1].ChildNodes.Count == 4);
            Assert.IsTrue(root.ChildNodes[2].ChildNodes.Count == 1);
        }

        /// <summary>
        ///A test for AdjustAddresses.
        ///</summary>
        [TestMethod()]
        public void AdjustAddressesTest()
        {
            string xml =
@"<root>
	<child1>
		<subChild1 />
		<subChild2 />
		<subChild3 />
	</child1>
	<child2>
		<subChild1>
		</subChild1>
		<subChild2>
			<subSubChild1>
				<subSubSubChild1 />
				<subSubSubChild2 />
				<subSubSubChild3 />
			</subSubChild1>
			<subSubChild2>
				<subSubSubChild1 />
			</subSubChild2>
			<subSubChild3>
				<subSubSubChild1 />
				<subSubSubChild2 />
			</subSubChild3>
		</subChild2>
		<subChild3 />
		<subChild4 />
	</child2>
	<child3>
		<subChild1 />
	</child3>
</root>";

            var root = TreeBuilder.BuildTree(xml);

            Assert.IsNotNull(root);
            TreeBuilder.AdjustAddresses(root, null);

            Assert.IsTrue(new int[] { 1, 1 }.SequenceEqual(root.ChildNodes[0].Address));
            Assert.IsTrue(new int[] { 1, 2 }.SequenceEqual(root.ChildNodes[1].Address));
            Assert.IsTrue(new int[] { 1, 3 }.SequenceEqual(root.ChildNodes[2].Address));

            Assert.AreEqual<BigXmlNode>(root, root.ChildNodes[0].Parent);
            Assert.AreEqual<BigXmlNode>(root, root.ChildNodes[1].Parent);
            Assert.AreEqual<BigXmlNode>(root, root.ChildNodes[2].Parent);

            Assert.IsTrue(new int[] { 1, 1, 1 }.SequenceEqual(root.ChildNodes[0].ChildNodes[0].Address));
            Assert.IsTrue(new int[] { 1, 1, 2 }.SequenceEqual(root.ChildNodes[0].ChildNodes[1].Address));
            Assert.IsTrue(new int[] { 1, 1, 3 }.SequenceEqual(root.ChildNodes[0].ChildNodes[2].Address));

            Assert.AreEqual<BigXmlNode>(root.ChildNodes[0], root.ChildNodes[0].ChildNodes[0].Parent);
            Assert.AreEqual<BigXmlNode>(root.ChildNodes[0], root.ChildNodes[0].ChildNodes[1].Parent);
            Assert.AreEqual<BigXmlNode>(root.ChildNodes[0], root.ChildNodes[0].ChildNodes[2].Parent);

            Assert.IsTrue(new int[] { 1, 2, 1 }.SequenceEqual(root.ChildNodes[1].ChildNodes[0].Address));
            Assert.IsTrue(new int[] { 1, 2, 2 }.SequenceEqual(root.ChildNodes[1].ChildNodes[1].Address));
            Assert.IsTrue(new int[] { 1, 2, 3 }.SequenceEqual(root.ChildNodes[1].ChildNodes[2].Address));
            Assert.IsTrue(new int[] { 1, 2, 4 }.SequenceEqual(root.ChildNodes[1].ChildNodes[3].Address));

            Assert.IsTrue(new int[] { 1, 3, 1 }.SequenceEqual(root.ChildNodes[2].ChildNodes[0].Address));

            Assert.IsTrue(new int[] { 1, 2, 2, 1 }.SequenceEqual(root.ChildNodes[1].ChildNodes[1].ChildNodes[0].Address));
            Assert.IsTrue(new int[] { 1, 2, 2, 2 }.SequenceEqual(root.ChildNodes[1].ChildNodes[1].ChildNodes[1].Address));
            Assert.IsTrue(new int[] { 1, 2, 2, 3 }.SequenceEqual(root.ChildNodes[1].ChildNodes[1].ChildNodes[2].Address));

            Assert.IsTrue(new int[] { 1, 2, 2, 1, 1 }.SequenceEqual(root.ChildNodes[1].ChildNodes[1].ChildNodes[0].ChildNodes[0].Address));
            Assert.IsTrue(new int[] { 1, 2, 2, 1, 2 }.SequenceEqual(root.ChildNodes[1].ChildNodes[1].ChildNodes[0].ChildNodes[1].Address));
            Assert.IsTrue(new int[] { 1, 2, 2, 1, 3 }.SequenceEqual(root.ChildNodes[1].ChildNodes[1].ChildNodes[0].ChildNodes[2].Address));

            Assert.IsTrue(new int[] { 1, 2, 2, 2, 1 }.SequenceEqual(root.ChildNodes[1].ChildNodes[1].ChildNodes[1].ChildNodes[0].Address));

            Assert.IsTrue(new int[] { 1, 2, 2, 3, 1 }.SequenceEqual(root.ChildNodes[1].ChildNodes[1].ChildNodes[2].ChildNodes[0].Address));
            Assert.IsTrue(new int[] { 1, 2, 2, 3, 2 }.SequenceEqual(root.ChildNodes[1].ChildNodes[1].ChildNodes[2].ChildNodes[1].Address));
        }
    }
}
